package test;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.*;

import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class Main {
    public static final String PRIVATE_KEY = "C:\\ideaprojects\\testencfile\\private.der";
    public static final String PUBLIC_KEY = "C:\\ideaprojects\\testencfile\\public.der";
    public static void encfile(){
        File file = new File(PRIVATE_KEY);
        String inputFile = "C:\\ideaprojects\\testencfile\\dism.log";
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            DataInputStream dis = new DataInputStream(fis);

            byte[] keyBytes = new byte[(int) file.length()];
            dis.readFully(keyBytes);
            dis.close();

            PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory kf = KeyFactory.getInstance("RSA");
            RSAPrivateKey privKey = (RSAPrivateKey) kf.generatePrivate(spec);
            System.out.println("Exponent :" + privKey.getPrivateExponent());
            System.out.println("Modulus" + privKey.getModulus());
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.ENCRYPT_MODE, privKey);
            DataInputStream pInRSA = new DataInputStream(new FileInputStream(inputFile));
            DataOutputStream eOutRSA = new DataOutputStream(new FileOutputStream(inputFile+".enc"));


            int blockSize = (2048 / 8) - 11;
            int count = 0;
            while (pInRSA.available() > 0) {
                byte[] buffer = new byte[Math.min(blockSize, pInRSA.available())];
                for (int i = 0; i < buffer.length; i++) {
                    buffer[i] = pInRSA.readByte();
                    count++;
                }
                byte[] encodedMsg = cipher.doFinal(buffer);
                eOutRSA.write(encodedMsg, 0, encodedMsg.length);
            }
            System.out.println(count);
            pInRSA.close();
            eOutRSA.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }
    }
    public static void decfile(){
        File file = new File(PUBLIC_KEY);
        String inputFile = "C:\\ideaprojects\\testencfile\\dism.log"+".enc";
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            DataInputStream dis = new DataInputStream(fis);

            byte[] keyBytes = new byte[(int) file.length()];
            dis.readFully(keyBytes);
            dis.close();

            X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
            KeyFactory kf1 = KeyFactory.getInstance("RSA");
            RSAPublicKey pubKey = (RSAPublicKey) kf1.generatePublic(spec);
            System.out.println("Exponent :" + pubKey.getPublicExponent());
            System.out.println("Modulus" + pubKey.getModulus());
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.DECRYPT_MODE, pubKey);
            DataInputStream pInRSA = new DataInputStream(new FileInputStream(inputFile));
            DataOutputStream eOutRSA = new DataOutputStream(new FileOutputStream(inputFile+".dec"));


            int blockSize = 256;

            int count = 0;
            int orincount = 0;
            while (pInRSA.available() > 0) {
               byte[] buffer = new byte[Math.min(blockSize, pInRSA.available())];
                for (int i = 0; i < buffer.length; i++) {
                    buffer[i] = pInRSA.readByte();
                    count++;
                }
                byte[] encodedMsg = cipher.doFinal(buffer);
                orincount += encodedMsg.length;
                eOutRSA.write(encodedMsg, 0, encodedMsg.length);
            }
            System.out.println(count);
            System.out.println(orincount);
            pInRSA.close();
            eOutRSA.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }

    }
    public static void main(String[] args) {
        encfile();
        decfile();

    }
}
